﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using HttpLib.Enum;
using HttpLib.Models;
using IdentityServer.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using WeChatIdentity.Constants;

namespace IdentityServer.Controllers
{
    [Route("api/v1/[controller]")]
    [ApiController]
    public class AuthorizeController : ControllerBase
    {
        private readonly IdentityServerSettings _settings;
        private readonly HttpClient _client;
        private readonly ILogger<AuthorizeController> _logger;
        public AuthorizeController(
            IOptionsSnapshot<IdentityServerSettings> settings,
            ILogger<AuthorizeController> logger)
        {
            _settings = settings.Value ?? throw new ArgumentNullException(nameof(settings));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            if (_client == null)
            {
                _client = new HttpClient();
            }
        }
        [HttpPost]
        [Route("authentication")]
        [ProducesResponseType(typeof(TokenModel), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> AuthenticationAsync([FromBody] AuthorizeRequest request, [FromHeader(Name = "x-requestid")] string requestId)
        {
            if (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty)
            {
                string openidUrl = string.Format(_settings.OpenIdUrl, request.Code);
                HttpResponseMessage response = await _client.GetAsync(openidUrl);
                string openId;
                if (response.IsSuccessStatusCode)
                {
                    OpenIdAndSessionKey openIdAndSessionKey = JsonConvert.DeserializeObject<OpenIdAndSessionKey>(response.Content.ReadAsStringAsync().Result);
                    if (!string.IsNullOrEmpty(openIdAndSessionKey.errmsg))
                    {
                        _logger.LogError("OpenId请求失败,error code:{errcode},error message:{errmsg}", openIdAndSessionKey.errcode, openIdAndSessionKey.errmsg);
                        return StatusCode(500, new ResultMsg { StatusCode = (int)StatusCodeEnum.InnerError, Message = $"Api签名失败:OpenId请求失败,请检查JSCode" });
                    }
                    else
                    {
                        openId = openIdAndSessionKey.openid;
                    }
                }
                else
                {
                    _logger.LogError("请求OpenId失败");
                    return StatusCode(500, $"请求OpenId失败");
                }
                string url = _settings.IdentityUrl + "connect/token";
                Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
                keyValuePairs.Add("client_id", _settings.ClientId);
                keyValuePairs.Add("client_secret", _settings.ClientSecret);
                keyValuePairs.Add("grant_type", _settings.GrantType);

                keyValuePairs.Add(ParamConstants.OpenId, openId);
                keyValuePairs.Add(ParamConstants.UserName, request.NickName);
                keyValuePairs.Add(ParamConstants.Country, request.Country);
                keyValuePairs.Add(ParamConstants.Province, request.Province);
                keyValuePairs.Add(ParamConstants.City, request.City);
                keyValuePairs.Add(ParamConstants.Gender, request.Gender.ToString());
                keyValuePairs.Add(ParamConstants.AvatarUrl, request.AvatarUrl);

                var identityrResponse = await PostAsync(url, keyValuePairs);
                if (identityrResponse.IsSuccessStatusCode)
                {
                    string result = await identityrResponse.Content.ReadAsStringAsync();
                    return Ok(result);
                }
                else
                {
                    return BadRequest();
                }
            }
            else
            {
                return BadRequest();
            }
        }

        private async Task<HttpResponseMessage> PostAsync(string url, Dictionary<string, string> keyValuePairs)
        {
            var content = new FormUrlEncodedContent(keyValuePairs);
            //content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
            return await _client.PostAsync(url, content);

        }
    }
}
